using System;
using System.Collections.Generic;
using System.Drawing;
using SharpWind.Input;

namespace SharpWind.Gui.Controls
{
	public abstract class TextBoxBase : ButtonBase
	{
		protected Label label = null;

		protected VScrollBar vScrollBar = null;

		protected ObjectCollection<string> lines = null;

		protected int maxLines = 0;

		protected int startLine = 0;

		protected int lineHeight = 0;

		protected bool showVScrollBar = false;

		public TextBoxBase( string control ) : base( control )
		{
			this.label				= new Label();
			this.label.Font			= Engine.Instance.Scene.Controls.Theme.Font;
			this.label.Text			= string.Empty;
			this.label.TextAlign	= TextAlign.MiddleLeft;
			this.label.TextColor	= Color.Black;
			this.vScrollBar			= new VScrollBar();
			this.vScrollBar.Minimum = 0;
			this.vScrollBar.Maximum = 0;
			this.vScrollBar.Value	= 0;
			this.vScrollBar.Step	= 1;
			this.vScrollBar.Enabled = this.startLine == 0 ? false : true;
			this.lines				= new ObjectCollection<string>();
			this.lineHeight			= Font.MeasureString( "A", TextColor ).Height;
			this.vScrollBar.ValueChanged += new EventHandler( OnVScrollBarValueChanged );
		}

		private void OnVScrollBarValueChanged( object sender, EventArgs e )
		{
			int amount = this.vScrollBar.Value - this.startLine;
			if( amount < 0 )
			{
				MoveTextLinesDown( Math.Abs( amount ) );
			}
			else if( amount > 0 )
			{
				amount = ( amount == this.vScrollBar.Step ) ? amount : this.vScrollBar.Step;
				MoveTextLinesUp( amount );
			}
		}

		internal override void MouseMove( MouseEventArgs e )
		{
			if( Visible && Enabled && ShowVScrollBar )
			{
				this.vScrollBar.MouseMove( e );
			}
		}

		internal override void MouseDown( MouseEventArgs e )
		{
			if( Visible && Enabled && ShowVScrollBar )
			{
				this.vScrollBar.MouseDown( e );
			}
		}

		internal override void MouseUp( MouseEventArgs e )
		{
			if( Visible && Enabled && ShowVScrollBar )
			{
				this.vScrollBar.MouseUp( e );
			}
		}

		internal override void MousePress( MouseEventArgs e )
		{
			if( Visible && Enabled && ShowVScrollBar )
			{
				this.vScrollBar.MousePress( e );
			}
		}

		internal override void Render()
		{
			if( Visible )
			{
				base.Render();

				OnRender();

				this.label.Render();

				if( ShowVScrollBar )
				{
					this.vScrollBar.Render();
				}
			}
		}

		protected virtual void OnRender()
		{
			
		}

		protected void MoveTextLinesUp( int amount )
		{
			if( this.lines.Count > this.maxLines &&
				( ( this.startLine + amount + this.maxLines ) <= this.lines.Count ) )
			{
				this.label.Text = string.Empty;
				this.startLine += amount;
				for( int i = startLine; i < this.startLine + this.maxLines; i++ )
				{
					this.label.Text += this.lines[i];
				}
			}
		}

		protected void MoveTextLinesDown( int amount )
		{
			if( this.startLine > 0 && this.startLine >= amount )
			{
				this.label.Text = string.Empty;
				this.startLine -= amount;

				for( int i = startLine; i < this.startLine + this.maxLines; i++ )
				{
					this.label.Text += this.lines[i];
				}
			}
		}

		protected void RecalculateElements()
		{
			this.label.Location		 = new PointF( Location.X + 2, Location.Y + 2 );
			this.vScrollBar.Location = new PointF( Location.X + Size.Width - vScrollBar.Size.Width - 4, Location.Y + 4 );
			this.vScrollBar.Size	 = new SizeF( this.vScrollBar.Size.Width, Size.Height - 8 );

			if( ShowVScrollBar )
			{
				this.label.Size = new SizeF( Size.Width - 8 - this.vScrollBar.Size.Width, Size.Height - 4 );
			}
			else
			{
				this.label.Size = new SizeF( Size.Width - 4, Size.Height - 4 );
			}
		}

		protected void CalculateMaxNumberOfLines()
		{
			this.maxLines = (int)Size.Height / this.lineHeight;
		}

		public Resources.Font Font
		{
			get
			{
				return this.label.Font;
			}
			set
			{
				if( this.label.Font != value )
				{
					this.label.Font = value;
					this.lineHeight = value.MeasureString( "A", TextColor ).Height;
					CalculateMaxNumberOfLines();
				}
			}
		}

		public TextAlign TextAlign
		{
			get
			{
				return this.label.TextAlign;
			}
			set
			{
				this.label.TextAlign = value;
			}
		}

		public Color TextColor
		{
			get
			{
				return this.label.TextColor;
			}
			set
			{
				if( this.label.TextColor != value )
				{
					this.label.TextColor = value;
					this.lineHeight		 = Font.MeasureString( "A", TextColor ).Height;
				}
			}
		}

		public override PointF Location
		{
			get
			{
				return base.Location;
			}
			set
			{
				if( base.Location != value )
				{
					base.Location = value;
					RecalculateElements();
				}
			}
		}

		public override SizeF Size
		{
			get
			{
				return base.Size;
			}
			set
			{
				if( base.Size != value )
				{
					base.Size = value;
					RecalculateElements();
					CalculateMaxNumberOfLines();
				}
			}
		}

		public bool ShowVScrollBar
		{
			get
			{
				return this.showVScrollBar;
			}
			set
			{
				if( this.showVScrollBar != value )
				{
					this.showVScrollBar = value;
					RecalculateElements();
				}
			}
		}

		public override bool Enabled
		{
			get
			{
				return base.Enabled;
			}
			set
			{
				if( base.Enabled != value )
				{
					base.Enabled = value;
					this.vScrollBar.Enabled = value;
				}
			}
		}

		internal int LineHeight
		{
			get
			{
				return this.lineHeight;
			}
		}
	}
}
